var temp = 0
var tool = 0

if !exists(param.A)
    ; Prompt the user to select a tool
    M291 S4 K{"T0 - Left Tool","T1 - Right Tool","Cancel"} R"Select a Tool" P"Choose the Left Tool (T0) or Right Tool (T1). Select ""Cancel"" to exit."

    ; Check the user's input and abort if 'Cancel' is selected
    if input != 0 && input != 1
        abort "Canceled"                                       ; Abort the macro if the user selects 'Cancel'

    ; Store the selected tool in a variable
    set var.tool = input

    ; Prompt the user to set the material print temperature
    M291 S5 J1 F250 L150 H450 R"Set Material Print Temperature" P"Enter the temperature for the filament last used in the selected tool."

    ; Store the user input in the 'temp' variable
    set var.temp = input

else
    set var.tool = state.currentTool
    set var.temp = param.A



; Initialize variables for temp_pull and temp_stop
var temp_pull = 0
var temp_stop = 0

; Check the temperature range and calculate temp_pull and temp_stop accordingly
if var.temp > 350                                          ; High Temp
    set var.temp_pull = {var.temp * 0.75}                  ; Calculate 'temp_pull'
    set var.temp_stop = {(var.temp + var.temp_pull) * 0.5} ; Calculate 'temp_stop'
else                                                       ; Low Temp
    set var.temp_pull = {var.temp * 0.6}                   ; Calculate 'temp_pull'
    set var.temp_stop = {(var.temp + var.temp_pull) * 0.5} ; Calculate 'temp_stop'

; Set the active tool to the selected tool
M568 P{var.tool} A2

; Set the tool temperature to 'temp'
M568 P{var.tool} R{var.temp} S{var.temp}

; Check if any of the axes are not homed, and home all if necessary
if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[3].homed
    M98 P"0:/sys/homeall.g" S1

; Lower build plate all the way down for easy filament spool removal
G90                                                        ; Absolute positioning
G1 Z420 F6000                                              ; Move to Z420 (max height, plate at bottom)

G91
if !exists(param.C)
  G1 Z100 F6000

; Deselect any active tool
T-1

; Select the tool based on the 'tool' variable
T{var.tool}

; Wait for the tool to reach the set temperature
M116 P{var.tool} S5

; Allow cold extrusion
M302 P1

; Set extruder moves to relative
M83
if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
  M568 P0 A0
  M568 P1 A0
  M140 S0
  M141 S0
  G1 X-999 U999 F18000 Y150 Z100 F18000
  M291 S1 R"Error" P"Heater fault detected"
  abort "Error: Heater fault detected"
; Extrude filament
G1 E50 F{5 * 60}
M400

; Lower the temperature below cold pull temp
M568 P{var.tool} R{var.temp_pull * 0.8} S{var.temp_pull * 0.8}

; Turn on the fan
M106 S1

; Extrude while lowering the temperature
while sensors.analog[{var.tool}].lastReading > {(var.temp_stop + var.temp) / 2}
    M400
    if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
      M568 P0 A0
      M568 P1 A0
      M140 S0
      M141 S0
      G1 X-999 U999 F18000 Y150 Z100 F18000
      M291 S1 R"Error" P"Heater fault detected"
      abort "Error: Heater fault detected"
    G1 E1 F{3 * 60}

; Extrude slowly while lowering the temperature
while sensors.analog[{var.tool}].lastReading > var.temp_stop
    M400
    if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
      M568 P0 A0
      M568 P1 A0
      M140 S0
      M141 S0
      G1 X-999 U999 F18000 Y150 Z100 F18000
      M291 S1 R"Error" P"Heater fault detected"
      abort "Error: Heater fault detected"
    G1 E1 F{1 * 60}

; Wait for the tool to reach the set temperature
M116 P{var.tool} S10

; Set cold pull temp and wait
M568 P{var.tool} R{var.temp_pull} S{var.temp_pull}
M116 P{var.tool} S5
M106 S0

; Set the tool temperature to temp_stop
M568 P{var.tool} R{var.temp_stop} S{var.temp_stop}

; Extrude while lowering the temperature further
while sensors.analog[{var.tool}].lastReading < {(var.temp_stop + var.temp_pull) / 2}
    M400
    if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
      M568 P0 A0
      M568 P1 A0
      M140 S0
      M141 S0
      G1 X-999 U999 F18000 Y150 Z100 F18000
      M291 S1 R"Error" P"Heater fault detected"
      abort "Error: Heater fault detected"
    G1 E-1 F{1 * 60}
    G4 P200

if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
  M568 P0 A0
  M568 P1 A0
  M140 S0
  M141 S0
  G1 X-999 U999 F18000 Y150 Z100 F18000
  M291 S1 R"Error" P"Heater fault detected"
  abort "Error: Heater fault detected"
; Retract filament
G1 E-20 F{5 * 60}
M400
G1 E-100 F{15 * 60}
M400

; Disallow cold extrusion
M302 P0

; Set the tool temperature to 0
M568 P{var.tool} R{0} S{0}

M98 P"0:/sys/led/end.g"                                    ; Green LED - success
M702 P0
; Prompt the user to manually remove the filament
M291 S3 R"✅ Cold Pull Complete" P{"Cold Pull procedure completed successfully!<br><br>You can now pull out the filament manually.<br>Build plate has been lowered for easy spool removal.<br><br>Click OK when done."}
M98 P"0:/sys/led/resetstatus.g"                            ; Reset LEDs to white